<?php
/** @noinspection PhpUnused */

namespace app\admin\controller\shop\goods;

use app\admin\controller\shop\Base;
use app\admin\model\shop\goods\Classify;
use app\admin\model\shop\goods\GoodsSku;
use app\shop\library\ShopLogHelper;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\helper\Arr;
use Throwable;

/**
 * 商品管理
 */
class Goods extends Base
{
    /**
     * Goods模型对象
     * @var object
     * @phpstan-var \app\admin\model\shop\goods\Goods
     */
    protected object $model;

    protected string|array $defaultSortField = 'weigh,desc';

    protected array|string $preExcludeFields = ['id', 'weigh', 'create_time', 'spec_data'];

    protected string|array $quickSearchField = ['name'];

    protected null|bool $autoSortEqWeight = true;

    protected string|array $indexField = ['*'];

    public function initialize(): void
    {
        parent::initialize();
        $this->model = new \app\admin\model\shop\goods\Goods;
        $this->request->filter('clean_xss');
    }


    /**
     * 若需重写查看、编辑、删除等方法，请复制 @see \app\admin\library\traits\Backend 中对应的方法至此进行重写
     */

    /**
     * 列表
     * @return void
     * @throws Throwable
     * @throws DbException
     */
    public function index(): void
    {
        if ($this->request->param('select')) {
            $this->select();
        }

        list($where, $alias, $limit, $order) = $this->queryBuilder();
        $res = $this->model
            ->field($this->indexField)
            ->with([
                'sku' => function ($query) {
                },
            ])
            ->withJoin($this->withJoinTable, $this->withJoinType)
            ->alias($alias)
            ->where($where)
            ->order($order)
            ->paginate($limit);

        $list = $this->buildClassifyName($res->items());

        $this->success('', [
            'list'   => $list,
            'total'  => $res->total(),
            'remark' => get_route_remark(),
        ]);
    }

    // 组装分类名称
    private function buildClassifyName(array $list): array
    {
        // 提取并展平分类ID
        $classifyIds = array_merge(...array_column($list, 'classify_id'));
        // 按照 '-' 符号分割分类ID，并去重
        $classifyIds = array_unique(
            array_reduce($classifyIds, function ($carry, $item) {
                return array_merge($carry, explode('-', $item));
            }, [])
        );
        // 查询分类名称
        $classifyNames = Classify::whereIn('id', $classifyIds)->column('name', 'id');
        // 将分类ID转换为分类名称
        foreach ($list as &$goods) {
            $names = [];
            foreach ($goods['classify_id'] as $classify) {
                list($firstId, $secondId) = explode('-', $classify);
                // 检查分类ID是否存在于分类名称数组中
                if (isset($classifyNames[$firstId], $classifyNames[$secondId])) {
                    $names[] = $classifyNames[$firstId] . '-' . $classifyNames[$secondId];
                }
            }
            $goods['classify_name'] = $names;
            unset($goods['classify_id']);
        }

        return $list;
    }

    /**
     * 远程搜搜
     * @return void
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function select(): void
    {
        $param = $this->request->param();

        $query = $this->model->where(['status' => 1]);

        if (Arr::get($param, 'classify_id')) {
            $query->whereFindInSet('classify_id', $param['classify_id']);
        }
        if (Arr::has($param, 'quickSearch')) {
            $name = $param['quickSearch'];
            $query->where('name', 'like', "%$name%");
        }

        $res = $query->field(['id', 'name'])->order(['id' => 'desc'])->select();

        $this->success('', [
            'list' => $res
        ]);
    }

    /**
     * 修改库存
     * @return void
     */
    public function editStock(): void
    {
        $param = $this->request->param();

        $goodsId = $param['goods_id'];
        $data    = $param['data'];

        $this->model->startTrans();
        try {
            $skuModel = new GoodsSku();
            $skuModel->saveAll($data);

            $newStock = array_sum(array_column($data, 'stock'));
            $this->model->update(['total_stock' => $newStock], ['id' => $goodsId]);
        } catch (Throwable $e) {
            $this->model->rollback();
            ShopLogHelper::error('库存修改失败', $data, $e);
            $this->error('修改失败');
        }
        $this->model->commit();

        $this->success();
    }
}